/*******************************************************************************
 * Copyright 2011 @ Kapil Viren Ahuja
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.kapilvirenahuja.eamsteps.parser;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import com.kapil.framework.exception.impl.DataProviderException;
import com.kapil.framework.logger.ILogger;
import com.kapil.framework.logger.LogFactory;
import com.kapilvirenahuja.eamsteps.datareader.IDataRow;
import com.kapilvirenahuja.eamsteps.info.HeaderInfo;

public class ExcelHeaderParser implements IHeaderParser
{
    private static final ILogger logger = LogFactory.getInstance().getLogger(ExcelHeaderParser.class);

    private static final List<String> supportedTypes = new ArrayList<String>(14);

    
    /**
     * Default constructor - initializes the list of supported header types. 
     */
    public ExcelHeaderParser()
    {
        supportedTypes.add("String");
        supportedTypes.add("Long");
        supportedTypes.add("Boolean");
        supportedTypes.add("Integer");
        supportedTypes.add("Date");
        supportedTypes.add("Reference");
        supportedTypes.add("Response");
    }
    
    
    /**
     * Parses the header as the Excel work-book format.
     */
    public HeaderInfo[] parseHeader(IDataRow headerRow, IDataRow datatypeRow)
    {
        int colCount = 2; // Work-sheet has been formatted such that the data starts from the 2nd column.
        List<HeaderInfo> headerDetails = new ArrayList<HeaderInfo>();


        // Continue while we can read values in the columns
        boolean continueReading = true;
        while (continueReading)
        {
            HeaderInfo header = new HeaderInfo(); // NOPMD because this is needed to avoid references.


            if (headerRow.getCell(colCount) == null || StringUtils.isEmpty(headerRow.getCell(colCount).getStringValue()))
            {
                // Stop reading the header if we found am empty column. Worksheet should have all headers in succession.
                continueReading = false;
            }
            else
            {
                header.setPropertyName(headerRow.getCell(colCount).getStringValue());

                // Check for the data type. If header exists, this is a mandatory field. A null value or a non-allowed
                // value should stop the execution.
                if (headerRow.getCell(colCount).getValue() == null || StringUtils.isEmpty(headerRow.getCell(colCount).getStringValue()))
                {
                    throw new DataProviderException("No Column type defined for [" + header.getPropertyName() + "].");
                }
                else
                {
                    // Check for valid column types.
                    String type = datatypeRow.getCell(colCount).getStringValue();
                    if (!supportedTypes.contains(type))
                    {
                        throw new DataProviderException("Invalid Column type for [" + header.getPropertyName() + "].");
                    }
                }


                header.setType(datatypeRow.getCell(colCount).getStringValue());
                headerDetails.add(header);

                logger.debug("Column: " + colCount + ". Details ##", header.toString());
            }

            colCount++;
        }

        if (CollectionUtils.isEmpty(headerDetails))
        {
            throw new DataProviderException("Header is mandatory to initialize data. Please validate excel workbook.");
        }

        logger.debug("Header has been succssfully initialized. Located [" + headerDetails.size() + "] columns.");
        return headerDetails.toArray(new HeaderInfo[headerDetails.size()]);
    }
}
